<?php


namespace app\api\model;


use app\common\library\IDMan;
use app\common\model\BaseModel;
use ApiOper;
use common;
use think\Db;

class UserReparkOrderModel extends BaseModel
{
    protected $name = 'user_repark_order';

    function submit($city_id, $bike_info, $ride_order_id,$bluetooth, $unlock)
    {
        if (empty($bike_info['bluetooth_token'])) {
            $bluetooth = 0;
        }

        if ($bike_info['bus_state'] != 0) {
            if ($bike_info['bus_state'] == BIKE_BUS_STAT_OPER_REPARK) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆挪车中!"];
            } else if ($bike_info['bus_state'] == BIKE_BUS_STAT_BATTERY_CHANGE) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆换电中!"];
            } else if($bike_info['bus_state'] == BIKE_BUS_STAT_USER_REPARK) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆挪车中!"];
            }
            else {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆骑行中!"];
            }
        }

        if ($bike_info['park_state'] != BIKE_PARK_STAT_OSA){
            return [USR_ORDER_ERROR_BIKE_BUSY, " 只有服务区外才能挪车!"];
        }

        $ID = IDMan::city_order_id($city_id);
        $order_state = USER_REPARK_ORDER_STATE_SUBMIT;
        $start_park_id = null;
        $start_park_name = null;


        $start_time = date('Y-m-d H:i:s');

        $usrinfo = ApiOper::instance()->_user_info;
        $order_info = [
            'id' => $ID,
            'city_id' => $city_id,
            'user_id' => $usrinfo['id'],
            'user_name' => $usrinfo['name'],
            'user_phone' => $usrinfo['phone'],
            'bike_id' => $bike_info['id'],
            'bike_sn' => $bike_info['sn'],
            'imei' => $bike_info['imei'],
            'order_state' => $order_state,
            'start_time' => $start_time,
            'start_park_state' => $bike_info['park_state'],
            'start_coordinate' => $bike_info['coordinate'],
            'start_address' => $bike_info['address'],
            'start_park_id' => $bike_info['park_id'],
            'start_park_name' => $bike_info['park_name'],
            'start_npa_id' => $bike_info['npa_id'],
            'start_npa_name' => $bike_info['npa_name'],
            'start_svca_id' => $bike_info['svca_id'],
            'start_svca_name' => $bike_info['svca_name'],
            'create_time' => date('Y-m-d H:i:s'),
            'track' => [
                [
                    $bike_info['coordinate'][0],
                    $bike_info['coordinate'][1],
                    date('Y-m-d H:i:s'),
                    $bike_info['speed'],
                    $bike_info['course'],
                ],
            ],
            'ride_order_id' => $ride_order_id,
        ];

        if (!empty(ApiOper::instance()->userinfo()['user_coordinate'])) {
            $order_info['user_start_coordinate'] = ApiOper::instance()->userinfo()['user_coordinate'];
        }

        (new BikeMgr())->user_repark_start($city_id, $bike_info['id'], $order_info, $bluetooth, $unlock);

        self::create('tb_user_repark_order', $order_info);


        $data = [
            'user_repark_order' => $ID,
            'user_repark_order_state' => $order_state,
        ];

        $where = [
            'id' => $ride_order_id,
        ];

        Db::table('tb_user_ride_order')->where($where)->update($data);

        return [0, '', $order_info];
    }

    function cs_submit($ride_order_info,$city_id, $bike_info, $ride_order_id,$bluetooth, $unlock)
    {
        if (empty($bike_info['bluetooth_token'])) {
            $bluetooth = 0;
        }

        if ($bike_info['bus_state'] != 0) {
            if ($bike_info['bus_state'] == BIKE_BUS_STAT_OPER_REPARK) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆挪车中!"];
            } else if ($bike_info['bus_state'] == BIKE_BUS_STAT_BATTERY_CHANGE) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆换电中!"];
            } else if($bike_info['bus_state'] == BIKE_BUS_STAT_USER_REPARK) {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆挪车中!"];
            }
            else {
                return [USR_ORDER_ERROR_BIKE_BUSY, " 车辆骑行中!"];
            }
        }

        if ($bike_info['park_state'] != BIKE_PARK_STAT_OSA){
            return [USR_ORDER_ERROR_BIKE_BUSY, " 只有服务区外才能挪车!"];
        }

        $ID = IDMan::city_order_id($city_id);
        $order_state = USER_REPARK_ORDER_STATE_SUBMIT;
        $start_park_id = null;
        $start_park_name = null;


        $start_time = date('Y-m-d H:i:s');

        //$usrinfo = ApiOper::instance()->_user_info;
        $order_info = [
            'id' => $ID,
            'city_id' => $city_id,
            'user_id' => $ride_order_info['user_id'],
            'user_name' => $ride_order_info['user_name'],
            'user_phone' => $ride_order_info['user_phone'],
            'bike_id' => $bike_info['id'],
            'bike_sn' => $bike_info['sn'],
            'imei' => $bike_info['imei'],
            'order_state' => $order_state,
            'start_time' => $start_time,
            'start_park_state' => $bike_info['park_state'],
            'start_coordinate' => $bike_info['coordinate'],
            'start_address' => $bike_info['address'],
            'start_park_id' => $bike_info['park_id'],
            'start_park_name' => $bike_info['park_name'],
            'start_npa_id' => $bike_info['npa_id'],
            'start_npa_name' => $bike_info['npa_name'],
            'start_svca_id' => $bike_info['svca_id'],
            'start_svca_name' => $bike_info['svca_name'],
            'create_time' => date('Y-m-d H:i:s'),
            'track' => [
                [
                    $bike_info['coordinate'][0],
                    $bike_info['coordinate'][1],
                    date('Y-m-d H:i:s'),
                    $bike_info['speed'],
                    $bike_info['course'],
                ],
            ],
            'ride_order_id' => $ride_order_id,
        ];

        if (!empty(ApiOper::instance()->userinfo()['user_coordinate'])) {
            $order_info['user_start_coordinate'] = ApiOper::instance()->userinfo()['user_coordinate'];
        }

        (new BikeMgr())->user_repark_start($city_id, $bike_info['id'], $order_info, $bluetooth, $unlock);

        self::create($order_info);


        $data = [
            'user_repark_order' => $ID,
            'user_repark_order_state' => $order_state,
        ];

        $where = [
            'id' => $ride_order_id,
        ];

        Db::table('tb_user_ride_order')->where($where)->update($data);

        return [0, '', $order_info];
    }

    function append_track($city_id, $order_id, $item)
    {
        $st = "update tb_user_repark_order set track = " . hisql::json_append_array_s('track', $item) . " where city_id = ? and id = ?";
        $beans = [$city_id, $order_id];
        hisql::db()->execute($st, $beans);
    }


    function finish($city_id, $order_id, $park_id, $bluetooth)
    {
        $order_info = $this->query_info($city_id, $order_id);
        if (empty($order_info)) {
            return [ERROR_QUERY_INFO, "finish order get order info error!"];
        }

        if ($order_info['order_state'] == USER_REPARK_ORDER_STATE_FINISHED) {
            return [ERROR_STATE_DISMATCH, "order_state = " . $order_info['order_state']];
        }

        $bike_info = (new BikeModel())->get_info_by_id($order_info['bike_id']);
        if (empty($bike_info)) {
            //订单异常
            $data = [
                'order_state' => -1,
            ];
            $where = [
                'city_id' => $city_id,
                'id' => $order_id,
            ];

            self::update($data, $where);
            return [ERROR_QUERY_INFO, "查询车辆信息失败！"];
        }

        if (empty($bike_info['bluetooth_token'])) {
            $bluetooth = 0;
        }

        $park = null;
        $toofar = false;
        if (time() - strtotime($bike_info['gps_update_time']) > 30) {
            $n = (new BikeMgr())->query_bike_info_rt($bike_info['imei']);
            if($n){
                $bike_info = (new BikeModel())->get_info_by_id($order_info['bike_id']);
            }
        }
        if ($park_id) {
            $park = (new ParkModel())->info($city_id, $park_id);
            if (empty($park)) {
                return [X_ERROR, "获取车站信息失败！"];
            }
            $distance = common::distance($park['coordinate'], $bike_info['coordinate']);
            if (($bike_info['park_state'] != BIKE_PARK_STAT_OSA && $bike_info['park_state'] != BIKE_PARK_STAT_NPA) && $distance > $park['radius']) {
                $toofar = true;
                if (!empty(ApiOper::instance()->userinfo()['user_coordinate'])) {
                    $distance_oper = common::distance($park['coordinate'], ApiOper::instance()->userinfo()['user_coordinate']);
                    if ($distance_oper < $park['radius']) {
                        $toofar = false;
                    }
                    $distance = min($distance_oper, $distance);
                }
            }

        } else {
            $park = (new ParkModel())->is_in($city_id, $bike_info['coordinate']);
        }

        $bound_order_info = [
            'order_type' => ORDER_TYPE_USER_REPARK,
            'order_id' => $order_info['id'],
            'op' => '用户结束挪车',
        ];

        if ($bike_info['is_defend_on'] == 0 && $bike_info['last_repark_order_id'] == $order_id) {
            if ($bike_info['last_repark_order_id'] == $order_id) {
                if (!$bluetooth) {
                    $ret = (new BikeMgr())->lock($city_id, $order_info['bike_id'], $bound_order_info);
                    if ($ret[0] != 0) {
                    }
                }
            }
        }

        $bike_info = BikeModel::instance()->get_info_by_id($order_info['bike_id']);

        $now = date('Y-m-d H:i:s');

        $park_state_info = [
            'park_state' => BIKE_PARK_STAT_FREE,
            'park_update_time' => date('Y-m-d H:i:s'),
        ];

        $service_area_info = (new ServiceAreaModel())->is_in($city_id, $bike_info['coordinate']);
        if (empty($service_area_info)) {
            $park_state_info['svca_id'] = null;
            $park_state_info['svca_name'] = null;
            $park_state_info['park_state'] = BIKE_PARK_STAT_OSA;
        } else {
            $park_state_info['svca_id'] = $service_area_info['id'];
            $park_state_info['svca_name'] = $service_area_info['name'];
        }

        $no_parking_area_info = (new NPAModel())->is_in($city_id, $bike_info['coordinate']);
        if (!empty($no_parking_area_info)) {
            $park_state_info['park_state'] = BIKE_PARK_STAT_NPA;
            $park_state_info['npa_id'] = $no_parking_area_info['id'];
            $park_state_info['npa_name'] = $no_parking_area_info['name'];
        } else {
            $park_state_info['npa_id'] = null;
            $park_state_info['npa_name'] = null;
        }

        if (!empty($park)) {
            $park_state_info['park_state'] = BIKE_PARK_STAT_PARK;
            $park_state_info['park_id'] = $park['id'];
            $park_state_info['park_name'] = $park['name'];
        } else {
            $park_state_info['park_id'] = null;
            $park_state_info['park_name'] = null;
        }
        $item = [
            floatval($bike_info['coordinate'][0]),
            floatval($bike_info['coordinate'][1]),
            date('Y-m-d H:i:s'),
            intval($bike_info['speed']),
            intval($bike_info['course']),
        ];

        //$this->append_track($city_id, $order_id, $item);
        $track = $order_info['track'];
        $track[] = $item;

        $duration = time() - strtotime($order_info['start_time']);
        $distance = $this->calc_miles($track);

        $data = [
            'order_state' => USER_REPARK_ORDER_STATE_FINISHED,
            'end_time' => $now,
            'end_coordinate' => json_encode($bike_info['coordinate']),
            'end_address' => $bike_info['address'],
            'track' => json_encode($track),
            'duration' => time() - strtotime($order_info['start_time']),
            'distance' => $distance,
            'end_park_state' => $park_state_info['park_state'],
            'end_park_id' => $park_state_info['park_id'],
            'end_park_name' => $park_state_info['park_name'],
            'end_npa_id' => $park_state_info['npa_id'],
            'end_npa_name' => $park_state_info['npa_name'],
            'end_svca_id' => $park_state_info['svca_id'],
            'end_svca_name' => $park_state_info['npa_name'],
        ];

        if (!empty(ApiOper::instance()->userinfo()['user_coordinate'])) {
            $data['user_end_coordinate'] = ApiOper::instance()->userinfo()['user_coordinate'];
        }
        $where = [
            'city_id' => $city_id,
            'id' => $order_id,
        ];

        self::update($data, $where);

        (new BikeMgr())->user_repark_finish($city_id, $bike_info['id'], $park_state_info);

        if ($bike_info['is_defend_on'] == 0 && $bike_info['last_repark_order_id'] == $order_id) {
            if ($bike_info['last_repark_order_id'] == $order_id) {
                if (!$bluetooth) {
                    (new BikeMgr())->asyn_check_defend_state($bike_info['id']);
                }
            }
        }


        $data1 = [
            'user_repark_order_state' => USER_REPARK_ORDER_STATE_FINISHED,
        ];

        $where1 = [
            'id' => $order_info['ride_order_id'],
        ];

        Db::table('tb_user_ride_order')->where($where1)->update($data1);


        //更新记录
        $com_info =[
            'bike_sn' => $bike_info['sn'],
            'com_staff_type' => OPER_TYPE_USER,
            'com_staff_id'   => $order_info['user_id'],
            'com_staff_name'   => $order_info['user_name'],
        ];

        (new BikeMgr())->asyn_warn_info($com_info);

        return [0, '', array_merge($order_info, $data)];
    }

    function query_info($city_id, $order_id)
    {
        $selectlist = [
            'id' => 'string',
            'city_id' => 'string',
            'user_id' => 'string',
            'user_name' => 'string',
            'user_phone' => 'string',
            'bike_id' => 'string',
            'imei' => 'string',
            'order_state' => 'int',
            'start_time' => 'string',
            'start_coordinate' => 'array',
            'start_address' => 'string',
            'start_park_id' => 'string',
            'start_park_name' => 'string',
            'end_time' => 'string',
            'end_coordinate' => 'array',
            'end_address' => 'string',
            'end_park_id' => 'string',
            'end_park_name' => 'string',
            'track' => 'array',
            'distance' => 'int',
            'duration' => 'int',
            'create_time' => 'string',
            'user_start_coordinate' => 'array',
            'user_end_coordinate' => 'array',
            'start_park_state' => 'int',
            'end_park_state' => 'int',
            'ride_order_id' => 'string',
        ];

        $sfs = common::array_keys($selectlist);
        $beans = [
            'city_id'=>$city_id,
            'id'=>$order_id,
        ];


        return $this->where($beans)->field($sfs)->find();
    }

    function query_track($city_id, $order_id)
    {
        $selectlist = [
            'bike_sn' => 'string',
            'start_time' => 'string',
            'end_time' => 'string',
            'start_coordinate' => 'array',
            'end_coordinate' => 'array',
            'start_park_state' => 'int',
            'end_park_state' => 'int',
            'track' => 'array',
        ];

        $sfs = common::array_keys($selectlist);
        $beans = [
            'city_id'=>$city_id,
            'id'=>$order_id,
        ];

        return $this->where($beans)->field($sfs)->find();
    }

    function calc_miles($track)
    {
        $miles = 0;
        for ($i = 1; $i < count($track); $i++) {
            $c1 = [$track[$i - 1][0], $track[$i - 1][1]];
            $c2 = [$track[$i][0], $track[$i][1]];
            $miles += common::distance($c1, $c2);
        }
        return $miles;
    }

    function query_list($city_id, $condition, $pos, $limit)
    {
        $selectlist = [
            'id' => 'string',
            'city_id' => 'string',
            'user_id' => 'string',
            'user_name' => 'string',
            'user_phone' => 'string',
            'bike_id' => 'string',
            'bike_sn' => 'string',
            'imei' => 'string',
            'order_state' => 'int',
            'start_time' => 'string',
            'start_coordinate' => 'array',
            'start_address' => 'string',
            'start_park_id' => 'string',
            'start_park_name' => 'string',
            'end_time' => 'string',
            'end_coordinate' => 'array',
            'end_address' => 'string',
            'end_park_id' => 'string',
            'end_park_name' => 'string',
            // 'track' => 'array',
            'distance' => 'int',
            'duration' => 'int',
            'create_time' => 'string',
            'channel' => 'string',
            'start_park_state' => 'int',
            'end_park_state' => 'int',
        ];
        $sfs = common::array_keys($selectlist);
        $beans = [
            'city_id'=>$city_id,
        ];

        if (isset($condition['is_start_from_park'])) {
            if ($condition['is_start_from_park']) {
                $beans['start_park_id'] = "not null";
            } else {
                $beans['start_park_id'] = "null";
            }
        }
        if (isset($condition['is_order_finished'])) {
            if ($condition['is_order_finished']) {
                $beans['order_state'] = REPARK_ORDER_STATE_FINISHED;
            } else {
                $beans['order_state'] = ['<',REPARK_ORDER_STATE_FINISHED];
            }
        }
        if (isset($condition['user_id'])) {
            $beans['user_id'] = $condition['user_id'];
        }
        if (isset($condition['start_park_state'])) {
            $beans['start_park_state'] = $condition['start_park_state'];
        }

        if (isset($condition['sk']) && !empty($condition['sk'])) {
            $sk = $condition['sk'];
            if (common::is_phone($sk)) {
                $beans['user_phone'] = $sk;
            } else if (IDMan::is_bike_sn($sk)) {
                $beans['bike_sn'] = $sk;
            } else if (common::is_name($sk)) {
                $beans['user_name'] = $sk;
            } else if (IDMan::is_bike_id($sk)) {
                $beans['bike_id'] = $sk;
            }
        }

        if (isset($condition['start_time'])) {
            $beans['create_time'] = ['>=',$condition['start_time']];
        }
        if (isset($condition['end_time'])) {
            $beans['create_time'] = ['<=',$condition['end_time']];
        }


        $rows = $this->where($beans)->field($sfs)->order('create_time','desc')->limit($pos,$limit)->select();
        return $rows->toArray();
    }

    function query_count()
    {
        return 100;
    }


    function get_user_unfinished_order($usr_id)
    {
//        $st = "select count(1) as total from tb_user_repark_order where user_id = ? and order_state < " . USER_REPARK_ORDER_STATE_FINISHED;
//        $beans = [
//            $usr_id,
//        ];
//
//        $result = hisql::db()->query($st, $beans);
//        $rows = $result->fetchAll(Phalcon\Db::FETCH_ASSOC);
//        return intval($rows[0]['total']);

        return $this->where('user_id','=',$usr_id)->where('order_state','<',USER_REPARK_ORDER_STATE_FINISHED)->count('id');
    }
}